// MinDigital.cpp : implementation file
//

#include "stdafx.h"
#include "MinDigital.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMinDigital

COLORREF CMinDigital::origin = RGB(255, 0, 0); 

CMinDigital::CMinDigital()
{
	HBITMAP temp = NULL;

	m_bAlarm = FALSE;
	m_style = XDC_NOSECOND;
	m_color = origin;
	
/*	for(int i = 0; i< 14; i++) 
	{
		temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i+IDB_DIGITAL0, 0, NULL, 0);
		m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
		if( temp != NULL )
			::DeleteObject(temp);
	}
*/
	m_oldyear = 0;
	m_oldmonth = 0;
	m_oldday = 0;
	m_oldhour = 0;
	m_oldminute = 0;
}

CMinDigital::~CMinDigital()
{
	for(int i = 0; i< 14; i++) 
	{
		if(m_hBitmap[i]) ::DeleteObject(m_hBitmap[i]);
	}
}


BEGIN_MESSAGE_MAP(CMinDigital, CStatic)
	//{{AFX_MSG_MAP(CMinDigital)
	ON_WM_TIMER()
	ON_WM_DESTROY()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMinDigital message handlers

void CMinDigital::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent == m_nTimer) 
	{
		m_nCount++;
		CRect rectClient;
		GetClientRect(&rectClient);
		m_h = rectClient.Height();

		if(m_style == XDC_SECOND) m_w = rectClient.Width()/19;
		else m_w = rectClient.Width()/16;

		CTime time = CTime::GetCurrentTime();

		int year = time.GetYear();
		int month = time.GetMonth();
		int day = time.GetDay();
		int hour = time.GetHour();
		int minute = time.GetMinute();

		int ny1, ny2, ny3, ny4;
		int nmo1, nmo2;
		int nd1, nd2;
		int nh1, nh2;
		int nm1, nm2;

		if( m_oldyear != year )
		{
			m_oldyear = year;

			ny1 = year / 1000;
			Output(ny1, 0);

			ny2 = year / 100;
			ny2 = ny2 % 10;
			Output(ny2, 1);

			ny3 = year / 10;
			ny3 = ny3 % 10;
			Output(ny3, 2);

			ny4 = year % 10;
			Output(ny4, 3);

			Output(13, 4);
		}

		if( m_oldmonth != month )
		{
			m_oldmonth = month;
			nmo1 = month / 10;
			if( nmo1 ) Output(nmo1, 5);
			else Output(10, 5);

			nmo2 = month % 10;
			Output(nmo2, 6);

			Output(13, 7);
		}

		if( m_oldday != day )
		{
			m_oldday = day;
			nd1 = day / 10;
			if( nd1 ) Output(nd1, 8);
			else Output(10, 8);

			nd2 = day % 10;
			Output(nd2, 9);

			Output(12, 10);
		}

		if( m_oldhour != hour )
		{
			m_oldhour = hour;
			nh1 = time.GetHour()/10;

			if(nh1) Output(nh1, 11);
			else Output(10, 11);
			
			nh2 = time.GetHour()%10;
			Output(nh2, 12);
		}

		if( m_oldminute != minute )
		{
			m_oldminute = minute;
			nm1 = time.GetMinute()/10;
			Output(nm1, 14);

			nm2 = time.GetMinute()%10;
			Output(nm2, 15);
		}

		switch(m_style) 
		{
			case XDC_SECOND:
			{
				int ns1 = time.GetSecond()/10;
   			Output(ns1, 17);
				int s2 = time.GetSecond()%10;
				Output(s2, 18);
				Output(10, 13); // double points
				Output(10, 16); // double points
			}
			break;
		
			case XDC_NOSECOND:
			
			default:
				if(m_bAlarm) Output(10, 13);
				else 
				{
					if(m_nCount%2) Output(10, 13); // double points
					else Output(11, 13); // 
				}
				break;
		}
		if(m_bAlarm) MessageBeep(0xffffffff);
	}
	CStatic::OnTimer(nIDEvent);
}

void CMinDigital::OnDestroy() 
{
	CStatic::OnDestroy();
	
	// TODO: Add your message handler code here
	
	// TODO: Add your message handler code here
	KillTimer(m_nTimer);	
}

BOOL CMinDigital::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	CBrush brush;
	brush.CreateSolidBrush( ::GetSysColor(COLOR_WINDOWTEXT) ); 
	CBrush* pOldBrush = pDC->SelectObject(&brush);

	CRect rectClient;
	GetClientRect(&rectClient);
	pDC->PatBlt(0, 0, rectClient.Width(), rectClient.Height(), PATCOPY);
	pDC->SelectObject(pOldBrush);

	brush.DeleteObject();
	if(pOldBrush) ::DeleteObject(pOldBrush);

	return CStatic::OnEraseBkgnd(pDC);
}

void CMinDigital::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	m_nCount++;
	CRect rectClient;
	GetClientRect(&rectClient);
	m_h = rectClient.Height();

	if(m_style == XDC_SECOND) m_w = rectClient.Width()/19;
	else m_w = rectClient.Width()/16;

	CTime time = CTime::GetCurrentTime();

	int year = time.GetYear();
	int month = time.GetMonth();
	int day = time.GetDay();
	int hour = time.GetHour();
	int minute = time.GetMinute();

	int ny1, ny2, ny3, ny4;
	int nmo1, nmo2;
	int nd1, nd2;
	int nh1, nh2;
	int nm1, nm2;

	m_oldyear = year;

	ny1 = year / 1000;
	Output(ny1, 0);

	ny2 = year / 100;
	ny2 = ny2 % 10;
	Output(ny2, 1);

	ny3 = year / 10;
	ny3 = ny3 % 10;
	Output(ny3, 2);

	ny4 = year % 10;
	Output(ny4, 3);

	Output(13, 4);

	m_oldmonth = month;
	nmo1 = month / 10;
	if( nmo1 ) Output(nmo1, 5);
	else Output(10, 5);

	nmo2 = month % 10;
	Output(nmo2, 6);

	Output(13, 7);

	m_oldday = day;
	nd1 = day / 10;
	if( nd1 ) Output(nd1, 8);
	else Output(10, 8);

	nd2 = day % 10;
	Output(nd2, 9);

	Output(12, 10);

	m_oldhour = hour;
	nh1 = time.GetHour()/10;

	if(nh1) Output(nh1, 11);
	else Output(10, 11);
	
	nh2 = time.GetHour()%10;
	Output(nh2, 12);

	m_oldminute = minute;
	nm1 = time.GetMinute()/10;
	Output(nm1, 14);

	nm2 = time.GetMinute()%10;
	Output(nm2, 15);

	switch(m_style) 
	{
		case XDC_SECOND:
		{
			int ns1 = time.GetSecond()/10;
   		Output(ns1, 17);
			int s2 = time.GetSecond()%10;
			Output(s2, 18);
			Output(10, 13); // double points
			Output(10, 16); // double points
		}
		break;
	
		case XDC_NOSECOND:
		
		default:
			if(m_bAlarm) Output(10, 13);
			else 
			{
				if(m_nCount%2) Output(10, 13); // double points
				else Output(11, 13); // 
			}
			break;
	}

	// Do not call CStatic::OnPaint() for painting messages
}

void CMinDigital::PreSubclassWindow() 
{
	// TODO: Add your specialized code here and/or call the base class
	// TODO: Add your specialized code here and/or call the base class
	//
	// Note: Set the Timer here Pls. 
	// Dont set timer in OnCreate(), you cant recieve WM_CREATE 
	// when control construted in Dialog template. Say: OnCreate not called.
	//
	m_nTimer = SetTimer(4, 1000, NULL);
	::GetObject(m_hBitmap[0], sizeof BITMAP, &m_bm);
	
	CStatic::PreSubclassWindow();
}

void CMinDigital::Output(UINT digit, UINT pos)
{
    // draw the bitmap
	CClientDC dc(this);
	CDC dcMem;
	dcMem.CreateCompatibleDC(&dc);

	// Alarm mode 
	if(m_bAlarm && m_nCount%2) digit = 11;

	CBitmap* pBitmap = CBitmap::FromHandle( m_hBitmap[digit] );
	CBitmap* pOldBitmap = dcMem.SelectObject(pBitmap);
	dc.StretchBlt(m_w*pos, 0, m_w, m_h, &dcMem, 0, 0, m_bm.bmWidth, m_bm.bmHeight, SRCCOPY);
 	dcMem.SelectObject(pOldBitmap);
	dcMem.DeleteDC();

	if( pBitmap != NULL )
		::DeleteObject(pBitmap);

	if( pOldBitmap != NULL )
		::DeleteObject(pOldBitmap);
}

CMinDigital::CClockStyle CMinDigital::SetStyle(CClockStyle style)
{
	CClockStyle temp = m_style;
	m_style = style;
//	if(::IsWindow(m_hWnd))
//		Invalidate();
	return temp;
}

COLORREF CMinDigital::SetColor(COLORREF color)
{
	if(m_color == color) return color;

	COLORREF temp = m_color;
	m_color = color;
	for(int i = 0; i< 14; i++) 
	{
		if(m_hBitmap[i]) ::DeleteObject(m_hBitmap[i]);
		COLORMAP	mapColor;
		mapColor.from = origin;
		mapColor.to  = color;
		HBITMAP temp = (HBITMAP)::CreateMappedBitmap(AfxGetApp()->m_hInstance, i, 0, &mapColor, 1);
		m_hBitmap[i] = (HBITMAP)::CopyImage( temp, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG | LR_COPYDELETEORG);
	}
	return temp;
}

BOOL CMinDigital::SetAlarm(BOOL bAlarm /*= TRUE*/)
{
	BOOL temp = m_bAlarm;
	m_bAlarm = bAlarm;
	return temp;
}

